<?php
/**
 * GioCMS
 * 
 * LICENSE
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE Version 2 
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-2.0.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@ninhgio.com so we can send you a copy immediately.
 * 
 * @copyright	Copyright (c) 2010-2011 GioCMS (http://cms.ninhgio.com)
 * @license		http://www.gnu.org/licenses/gpl-2.0.txt GNU GENERAL PUBLIC LICENSE Version 2
 * @author		NinhGio - ninhgio@gmail.com
 * @since		1.0
 */

class Gio_Core_Widget
{
	protected $_module = null;
	protected $_widget = null;
	protected $_action = null;
	protected $_cacheEnable = false;
	protected $_cacheTimeout = 3600;
	protected $_template = 'default';
	protected $_content = null;
	protected $_paramString = null;
	/**
	 * @var Gio_Core_Request
	 */
	protected $_request = null;
	/**
	 * @var Gio_Core_Response
	 */
	protected $_response = null;
	
	protected $_params = array();
	
	/**
	 * @var Gio_Core_View
	 */
	protected $view = null;
	
	/**
	 * @var Gio_Core_Widget
	 */
	private static $_instance = null;
	
	/**
	 * @var Modules_Core_Models_Mysql_Translation
	 */
	private $_translationDao;
	
	/**
	 * @return Gio_Core_Widget
	 */
	public static function getIntance()
	{
		if (null == self::$_instance) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}
	
	public function __construct()
	{
		$this->view = clone Gio_Core_View::getInstance();
		$this->_request = Gio_Core_Request::getInstance();
		$this->_response = Gio_Core_Response::getInstance();
		$this->_translationDao = new Modules_Core_Models_Mysql_Translation();
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setParams($params)
	{
		$this->_params = $params;
		return $this;
	}
	
	public function getModuleName()
	{
		return $this->_module;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setModuleName($name)
	{
		$this->_module = strtolower($name);
		return $this;
	}
	
	public function getWidgetName()
	{
		return $this->_widget;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setWidgetName($name)
	{
		$this->_widget = strtolower($name);
		return $this;
	}
	
	public function getActionName()
	{
		return $this->_action;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setActionName($name)
	{
		$this->_action = strtolower($name);
		return $this;
	}
	
	public function getCacheEnable()
	{
		return $this->_cacheEnable;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setCacheEnable($value)
	{
		$this->_cacheEnable = ($value == true) ? true : false;
		return $this;
	}
	
	public function getCacheTimeout()
	{
		return $this->_cacheTimeout;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setCacheTimeout($timeout)
	{
		$this->_cacheTimeout = $timeout;
		return $this;
	}
	
	public function getLayout()
	{
		return $this->_layout;
	}
	
	public function getTemplate()
	{
		return $this->_template;
	}
	
	/**
	 * @return Gio_Core_Widget
	 */
	public function setTemplate($name)
	{
		$this->_template = strtolower($name);
		return $this;
	}
	
	/**
	 * @return Gio_Core_Request
	 */
	public function getRequest()
	{
		return $this->_request;
	}
		
	public function setParamString($string)
	{
		$this->_paramString = $string;
		return $this;
	} 
	
	public function getParam($name, $defaultValue = null)
	{
		return (isset($this->_params[$name]))
						? $this->_params[$name] : $defaultValue;
	}
	
	public function dispatch()
	{
		$cacheType = 'widgets';
		$request = $this->_request;
		/**
		 * XML
		 */
		$xmlFilename = array(
							$this->_module,
							$this->_widget,
							$this->_action,
					);
		$xmlFilename = implode('_', $xmlFilename);
		
		/**
		 * Check file html cache 
		 */
		$globalConfig = Gio_Core_Config_Xml::getConfig();
		$configs = Gio_Core_Config_Xml::getConfig('cache');
		$checkCache = false;
		if ($configs->enable == 'true' && $this->_cacheEnable == true) {
			$cacheName = $xmlFilename;
			$postParams = $request->getPostParams();
			$getParams = $request->getParams();
			$widgetParams = $this->_params;
			
			$json = new Services_JSON();
			$cacheParams = (!empty($postParams)) ? base64_encode($json->encodeUnsafe($postParams)) : null;
			$cacheParams = (!empty($getParams)) ? base64_encode($json->encodeUnsafe($getParams)) : null;
			$cacheParams = (!empty($widgetParams)) ? base64_encode($json->encodeUnsafe($widgetParams)) : null;
				
			$cacheKey = md5($cacheName . $this->_template . $cacheParams . base64_encode($json->encodeUnsafe($globalConfig)));
								
			$cacheTimeout = $this->_cacheTimeout ? $this->_cacheTimeout : 3600;
			/**
			 * Create html file cache
			 */
			if (($checkCache = Gio_Core_Cache::isCached($cacheType, $cacheKey, $cacheTimeout))) {
				$html = $this->view->render(Gio_Core_Cache::_generateFileName($cacheType, $cacheKey));
				return $html;
			}
		}
		
		/**
		 * Localization config 
		 */
		$aboutFile = ROOT_DIR . DS . 'modules' . DS . $this->_module . DS . 'widgets' . DS . $this->_widget . DS . 'about.xml';
		if (file_exists($aboutFile)) {
			$info         = @simplexml_load_file($aboutFile);
			$localization = $info->localization['enable'];
			
			if ($localization != null && 'true' == (string)$localization) {
				$idClass = (string) $info->localization->identifier['class'];
				$idParam = (string) $info->localization->identifier['param'];
				
				$this->_params[$idParam] = (isset($this->_params[$idParam]))
												? $this->_params[$idParam] : null;
				
				$conn = Gio_Db_Connection::getConnection();
				$this->_translationDao->setConnection($conn);
				$items = $this->_translationDao->getItems($this->_params[$idParam], $idClass, $request->getParam('lang'));
				
				if ($items != null && 1 == count($items)) {
					$this->_params[$idParam] = $items[0]['item_id'];
				}
			}
		}
		
		$ucfModule	     = ucfirst($this->_module);
		$ucfWidget   	 = ucfirst($this->_widget);
		$widgetClassName = array(
								'Modules',
								$ucfModule,
								'Widgets',
								$ucfWidget,
								'Widget'
							); 
		$widgetClassName = implode('_', $widgetClassName);
		$widgetClass	 = new $widgetClassName();
		if (!method_exists($widgetClass, $this->_action . 'Action')) {
			return;
		}
		
		$widgetClass->setParams($this->_params);
		call_user_func(array($widgetClass, $this->_action . 'Action'));
		
		$widgetDefaultViewFile = MOD_DIR . DS . $this->_module . DS . 'widgets' . DS . $this->_widget
								. DS . $this->_action . '.phtml';
		$widgetViewFile = TEMPLATE_DIR . DS . $this->_template . DS . 'modules' 
								. DS . $this->_module . DS . 'widgets' . DS . $this->_widget
								. DS . $this->_action . '.phtml';
								
		$widgetViewFile = (file_exists($widgetViewFile)) ? $widgetViewFile : $widgetDefaultViewFile;
			
		$widgetClass->view->cacheEnable = $this->_cacheEnable;
		$widgetClass->view->cacheTimeout = $this->_cacheTimeout;
								
		$return = $widgetClass->view->render($widgetViewFile);
		
		if (!isset($this->_params['load']) || $this->_params['load'] != 'ajax') {
			$jsCss = array(
				'cssFiles'	=> array(), 
				'jsFiles'   => array(),
			);
			$search  = array(
							'{APP_WEB_URL}', 
							'{APP_STATIC_SERVER}',
							'{WIDGET_URL}',
						);
			$replace = array(
							$this->view->APP_WEB_URL, 
							$this->view->APP_STATIC_SERVER,
							$this->view->APP_STATIC_SERVER . DS . 'modules' . DS . strtolower($this->_module) . DS . 'widgets' . DS . strtolower($this->_widget),
					);
			$configFile = ROOT_DIR . DS . 'modules' . DS . strtolower($this->_module) . DS . 'widgets' . DS . strtolower($this->_widget) . DS . 'about.xml';
			if (file_exists($configFile)) {
				$widgetConfig = @simplexml_load_file($configFile);
				if (($resources = $widgetConfig->resources)) {
					if ($resources = $resources->resource) {
						foreach ($resources as $resource) {
							$attr = $resource->attributes();
							
							switch ((string) $attr['type']) {
								case 'css':
									$jsCss['cssFiles'][] = str_replace($search, $replace, (string) $attr['src']);
									break;
								case 'javascript':
									$jsCss['jsFiles'][]  = str_replace($search, $replace, (string) $attr['src']);
									break;
							}
						}
					}
				}
			}
			
			if ($jsCss['cssFiles']) {
				foreach ($jsCss['cssFiles'] as $index => $file) {
					Gio_Core_View::getInstance()->headStyle($file);
				}
			}
			
			if ($jsCss['jsFiles']) {
				foreach ($jsCss['jsFiles'] as $index => $file) {
					Gio_Core_View::getInstance()->headScript($file);
				}
			}
		}
		
		if (!$checkCache && $configs->enable == 'true' && $this->_cacheEnable == true) {
			$cacheCompress = (isset($configs->compress) && $configs->compress == 'true')
									? true : false;
			$cacheContent = Gio_Core_View::getInstance()->generateScripts()
								 . Gio_Core_View::getInstance()->generateStyles() . $return;
			/**
			 * HTML Compress
			 */
			if (isset($configs->compress) && $configs->compress == 'true') {
				$cacheContent = Gio_Core_HtmlCompress::compress($cacheContent);
			}
			Gio_Core_Cache::cache($cacheType, $cacheKey, $cacheContent, $cacheCompress);
		}
		
		return $return;
	}
}